package com.spring.boot.observer;

import java.util.Observer;
import java.util.Observable;

/**
 * 在 Java 中，通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式，
 * 只要实现它们的子类就可以编写观察者模式实例。
 * 1. Observable类
 * Observable 类是抽象目标类，它有一个 Vector 向量，用于保存所有要通知的观察者对象，下面来介绍它最重要的 3 个方法。
 * void addObserver(Observer o) 方法：用于将新的观察者对象添加到向量中。
 * void notifyObservers(Object arg) 方法：调用向量中的所有观察者对象的 update。方法，通知它们数据发生改变。通常越晚加入向量的观察者越先得到通知。
 * void setChange() 方法：用来设置一个 boolean 类型的内部标志位，注明目标对象发生了变化。当它为真时，notifyObservers() 才会通知观察者。
 * 2. Observer 接口
 * Observer 接口是抽象观察者，它监视目标对象的变化，当目标对象发生变化时，观察者得到通知，
 * 并调用 void update(Observable o,Object arg) 方法，进行相应的工作
 */
public class CrudeOilFutures {
    public static void main(String[] args) {
        OilFutures oil=new OilFutures();
        Observer bull=new Bull(); //卖方
        Observer bear=new Bear(); //买方
        oil.addObserver(bull);
        oil.addObserver(bear);
        oil.setPrice(10);
        oil.setPrice(-8);
    }

}

//具体目标类：原油期货
class OilFutures extends Observable {
    private float price;
    private float getPrice(){
        return this.price;
    }
    public void setPrice(float price) {
        super.setChanged() ;            //设置内部标志位，注明数据发生变化
        super.notifyObservers(price);   //通知观察者价格改变了
        this.price=price ;
    }
}
//具体观察者类：卖方
class Bull implements Observer{

    public void update(Observable o, Object arg) {
        float price = ((Float) arg).floatValue();
        if (price > 0){
            System.out.println("油价上涨了："+price +" 元，卖方高兴了");
        }else {
            System.out.println("油价上涨了："+(-price) +" 元，卖方伤心了");
        }
    }
}

//具体观察者类：买方
class Bear implements Observer{

    public void update(Observable o, Object arg) {
        Float price=((Float)arg).floatValue();
        if(price>0) {
            System.out.println("油价上涨"+price+"元，买方伤心了！");
        } else {
            System.out.println("油价下跌"+(-price)+"元，买方高兴了！");
        }
    }
}
